package com.yanxu.bio.V2.server;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author 折戟沉沙铁未销
 * @version V1.0
 * @date 2024/12/21-2024
 * @Description: bio服务端
 */
public class ChatRoomServer {

    private static Map<Integer, Writer> messageClientMap = new ConcurrentHashMap<>();

    ExecutorService subExecutorService = Executors.newFixedThreadPool(10);

    ServerSocket serverSocket = null;

    public void start() {
        try {
            //主线程： 启动监听
            serverSocket = new ServerSocket(8080);

            while (true) {
                //主线程： 接受客户端的连接请求
                Socket socket = serverSocket.accept();
                System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + " ---> 上线了！");
                //主线程： 计算出该客户端的一个唯一性的 hashcode 值
                int hashCode = (socket.getInetAddress().getHostAddress() + socket.getPort()).hashCode();

                //主线程只负责接受客户端的请求。
                //因此：针对每一个客户端的连接请求，使用线程池中的线程处理与该客户端的业务逻辑。
                subExecutorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            //获取read、writer
                            InputStream inputStream = socket.getInputStream();
                            OutputStream outputStream = socket.getOutputStream();
                            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));

                            //添加到客户端集合列表中
                            messageClientMap.put(hashCode, writer);

                            //读取该客户端的消息，并进行转发
                            String msg = null;
                            while ((msg = reader.readLine()) != null) {
                                System.out.println("----" + msg);
                                for (Integer i : messageClientMap.keySet()) {
                                    if (i == hashCode) {
                                        continue;
                                    }
                                    Writer getWriter = messageClientMap.get(i);
                                    String fwdMsg = "客户端[" + socket.getPort() + "]: " + msg + "\n";
                                    getWriter.write(fwdMsg + "\n");
                                    getWriter.flush();
                                }

                                //如果收到的消息是 quit. 那么证明该客户端要退出了
                                if (msg.equals("quit")) {
                                    break;
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            messageClientMap.remove(hashCode);  //从客户端列表集合中将该客户端移除
                        }
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ChatRoomServer chatRoomServer = new ChatRoomServer();
        chatRoomServer.start();

    }
}